home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 85 / CD Temático 40 Febrero 2004.iso / DOS / testdisk / src / dir.c < prev    next >
Encoding:
C/C++ Source or Header  |  2004-01-08  |  9.0 KB  |  348 lines

  1. /*
  2.  
  3.     File: dir.c
  4.  
  5.     Copyright (C) 1998-2004 Christophe GRENIER <grenier@cgsecurity.org>
  6.   
  7.     This software is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU General Public License as published by
  9.     the Free Software Foundation; either version 2 of the License, or
  10.     (at your option) any later version.
  11.   
  12.     This program is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.   
  17.     You should have received a copy of the GNU General Public License
  18.     along with this program; if not, write to the Free Software
  19.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  
  21.  */
  22. #include <stdio.h>
  23. #include <ctype.h>    /* toupper */
  24. #include <string.h>
  25. #include <stdlib.h>
  26. #include <time.h>
  27. #include <sys/stat.h>
  28. #include <unistd.h>
  29. #include "types.h"
  30. #include "common.h"
  31. #include "fat.h"
  32. #include "lang.h"
  33. #include "fnctdsk.h"
  34. #include "testdisk.h"
  35. #include "intrface.h"
  36. #include "dir.h"
  37. static const char *monstr[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  38.                 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
  39. static void mode_string (const unsigned int mode, char *str);
  40. static char ftypelet (unsigned int bits);
  41.  
  42. static char ftypelet (unsigned int bits)
  43. {
  44. #ifdef LINUX_S_ISBLK
  45.   if (LINUX_S_ISBLK (bits))
  46.     return 'b';
  47. #endif
  48.   if (LINUX_S_ISCHR (bits))
  49.     return 'c';
  50.   if (LINUX_S_ISDIR (bits))
  51.     return 'd';
  52.   if (LINUX_S_ISREG (bits))
  53.     return '-';
  54. #ifdef LINUX_S_ISFIFO
  55.   if (LINUX_S_ISFIFO (bits))
  56.     return 'p';
  57. #endif
  58. #ifdef LINUX_S_ISLNK
  59.   if (LINUX_S_ISLNK (bits))
  60.     return 'l';
  61. #endif
  62. #ifdef LINUX_S_ISSOCK
  63.   if (LINUX_S_ISSOCK (bits))
  64.     return 's';
  65. #endif
  66. #ifdef LINUX_S_ISMPC
  67.   if (LINUX_S_ISMPC (bits))
  68.     return 'm';
  69. #endif
  70. #ifdef LINUX_S_ISNWK
  71.   if (LINUX_S_ISNWK (bits))
  72.     return 'n';
  73. #endif
  74. #ifdef LINUX_S_ISDOOR
  75.   if (LINUX_S_ISDOOR (bits))
  76.     return 'D';
  77. #endif
  78. #ifdef LINUX_S_ISCTG
  79.   if (LINUX_S_ISCTG (bits))
  80.     return 'C';
  81. #endif
  82. #ifdef LINUX_S_ISOFD
  83.   if (LINUX_S_ISOFD (bits))
  84.     /* off line, with data  */
  85.     return 'M';
  86. #endif
  87. #ifdef LINUX_S_ISOFL
  88.   /* off line, with no data  */
  89.   if (LINUX_S_ISOFL (bits))
  90.     return 'M';
  91. #endif
  92.   return '?';
  93. }
  94.  
  95. void mode_string (const unsigned int mode, char *str)
  96. {
  97.   str[0] = ftypelet(mode);
  98.   str[1] = mode & LINUX_S_IRUSR ? 'r' : '-';
  99.   str[2] = mode & LINUX_S_IWUSR ? 'w' : '-';
  100.   str[3] = mode & LINUX_S_IXUSR ? 'x' : '-';
  101.   str[4] = mode & LINUX_S_IRGRP ? 'r' : '-';
  102.   str[5] = mode & LINUX_S_IWGRP ? 'w' : '-';
  103.   str[6] = mode & LINUX_S_IXGRP ? 'x' : '-';
  104.   str[7] = mode & LINUX_S_IROTH ? 'r' : '-';
  105.   str[8] = mode & LINUX_S_IWOTH ? 'w' : '-';
  106.   str[9] = mode & LINUX_S_IXOTH ? 'x' : '-';
  107.   str[10]='\0';
  108. #ifdef LINUX_S_ISUID
  109.   if (mode & LINUX_S_ISUID)
  110.   {
  111.     if (str[3] != 'x')
  112.       /* Set-uid, but not executable by owner.  */
  113.       str[3] = 'S';
  114.     else
  115.       str[3] = 's';
  116.   }
  117. #endif
  118. #ifdef LINUX_S_ISGID
  119.   if (mode & LINUX_S_ISGID)
  120.   {
  121.     if (str[6] != 'x')
  122.       /* Set-gid, but not executable by group.  */
  123.       str[6] = 'S';
  124.     else
  125.       str[6] = 's';
  126.   }
  127. #endif
  128. #ifdef LINUX_S_ISVTX
  129.   if (mode & LINUX_S_ISVTX)
  130.   {
  131.     if (str[9] != 'x')
  132.       /* Sticky, but not executable by others.  */
  133.       str[9] = 'T';
  134.     else
  135.       str[9] = 't';
  136.   }
  137. #endif
  138. }
  139.  
  140. void dir_aff_log(const t_param_disk *disk_car, const t_diskext *partition, const t_dir_data *dir_data, const t_file_data*dir_list)
  141. {
  142.   const t_file_data *current_file;
  143.   aff_part_rapport(disk_car,partition);
  144.   if(dir_data!=NULL)
  145.   {
  146.     ecrit_rapport("Directory %s\n",dir_data->current_directory);
  147.   }
  148.   for(current_file=dir_list;current_file!=NULL;current_file=current_file->next)
  149.   {
  150.     struct tm        *tm_p;
  151.     char        datestr[80];
  152.     char str[11];
  153.     if(current_file->filestat.st_mtime)
  154.     {
  155.       tm_p = localtime(¤t_file->filestat.st_mtime);
  156.       sprintf(datestr, "%2d-%s-%4d %02d:%02d",
  157.       tm_p->tm_mday, monstr[tm_p->tm_mon],
  158.       1900 + tm_p->tm_year, tm_p->tm_hour,
  159.       tm_p->tm_min);
  160.     } else {
  161.       strncpy(datestr, "                 ",sizeof(datestr));
  162.     }
  163.     mode_string(current_file->filestat.st_mode,str);
  164.     ecrit_rapport("%s %5u  %5u   ", 
  165.     str, current_file->filestat.st_uid, current_file->filestat.st_gid);
  166.     ecrit_rapport("%7llu", (long long unsigned int)current_file->filestat.st_size);
  167.     ecrit_rapport(" %s %s\n", datestr, current_file->name);
  168.   }
  169. }
  170.  
  171. long int dir_aff(t_param_disk *disk_car, const t_diskext *partition, t_dir_data *dir_data, const t_file_data*dir_list, const unsigned long int inode)
  172. {
  173.   /* Return value
  174.    * -1: quit
  175.    *  1: back
  176.    *  other: new inode
  177.    * */
  178.   int quit;
  179.   int offset=0;
  180.   int pos_num=0;
  181.   const t_file_data *current_file;
  182.   const t_file_data *pos=dir_list;
  183.   aff_copy(dir_data->window);
  184.   wmove(dir_data->window,4,0);
  185.   aff_part(dir_data->window,AFF_PART_NONL,disk_car,partition);
  186.   mvwaddstr(dir_data->window,5,0,"Use arrow keys to change directory, enter to quit");
  187.   wmove(dir_data->window,6,0);
  188.   wdoprintf(dir_data->window,"Directory %s\n",dir_data->current_directory);
  189.   do
  190.   {
  191.     int i;
  192.     int car;
  193.     for(i=0,current_file=dir_list;(current_file!=NULL) && (i<offset);current_file=current_file->next,i++);
  194.     for(i=offset;(current_file!=NULL) &&((i-offset)<INTER_STRUCTURE);i++,current_file=current_file->next)
  195.     {
  196.       struct tm        *tm_p;
  197.       char str[11];
  198.       char        datestr[80];
  199.       wmove(dir_data->window,8+i-offset,0);
  200.       wclrtoeol(dir_data->window);    /* before addstr for BSD compatibility */
  201.       if(current_file==pos)
  202.     wstandout(dir_data->window);
  203.       if(current_file->filestat.st_mtime!=0)
  204.       {
  205.     tm_p = localtime(¤t_file->filestat.st_mtime);
  206.     sprintf(datestr, "%2d-%s-%4d %02d:%02d",
  207.         tm_p->tm_mday, monstr[tm_p->tm_mon],
  208.         1900 + tm_p->tm_year, tm_p->tm_hour,
  209.         tm_p->tm_min);
  210.       } else {
  211.     strncpy(datestr, "                 ",sizeof(datestr));
  212.       }
  213.       mode_string(current_file->filestat.st_mode,str);
  214.       wdoprintf(dir_data->window, "%s %5u %5u   ", 
  215.       str, current_file->filestat.st_uid, current_file->filestat.st_gid);
  216.       wdoprintf(dir_data->window, "%7llu", (long long unsigned int)current_file->filestat.st_size);
  217.       wdoprintf(dir_data->window, " %s %s\n", datestr, current_file->name);
  218.       if(current_file==pos)
  219.     wstandend(dir_data->window);
  220.     }
  221.     wrefresh(dir_data->window);
  222.     car=wgetch(dir_data->window);
  223.     quit=0;
  224.     switch(car)
  225.     {
  226.       case 'q':
  227.       case '\r':
  228.       case '\n':
  229.       case 'M':
  230.       case KEY_ENTER:
  231. #ifdef PADENTER
  232.       case PADENTER:
  233. #endif
  234.     quit=1;
  235.     break;
  236.     }
  237.     if(dir_list!=NULL)
  238.     {
  239.       switch(car)
  240.       {
  241.     case KEY_UP:
  242.       if(pos->prev!=NULL)
  243.       {
  244.         pos=pos->prev;
  245.         pos_num--;
  246.       }
  247.       if(pos_num<offset)
  248.         offset--;
  249.       break;
  250.     case KEY_DOWN:
  251.       if(pos->next!=NULL)
  252.       {
  253.         pos=pos->next;
  254.         pos_num++;
  255.       }
  256.       if(pos_num>=offset+INTER_STRUCTURE)
  257.         offset++;
  258.       break;
  259.     case '+':
  260.     case ' ':
  261.     case KEY_RIGHT:
  262.       if((pos!=NULL) && (LINUX_S_ISDIR(pos->filestat.st_mode)!=0))
  263.       {
  264.         unsigned long int new_inode=pos->filestat.st_ino;
  265.         if(new_inode!=inode)
  266.         {
  267.           if(strcmp(pos->name,"..")==0)
  268.         return 1;
  269.           if(strlen(dir_data->current_directory)+1+strlen(pos->name)<sizeof(dir_data->current_directory)-1)
  270.           {
  271.         if(strcmp(dir_data->current_directory,"/"))
  272.           strcat(dir_data->current_directory,"/");
  273.         strcat(dir_data->current_directory,pos->name);
  274.         return (long int)new_inode;
  275.           }
  276.         }
  277.       }
  278.       break;
  279.     case KEY_PPAGE:
  280.       for(i=0;(i<INTER_STRUCTURE-1)&&(pos->prev!=NULL);i++)
  281.       {
  282.         pos=pos->prev;
  283.         pos_num--;
  284.         if(pos_num<offset)
  285.           offset--;
  286.       }
  287.       break;
  288.     case KEY_NPAGE:
  289.       for(i=0;(i<INTER_STRUCTURE-1)&&(pos->next!=NULL);i++)
  290.       {
  291.         pos=pos->next;
  292.         pos_num++;
  293.         if(pos_num>=offset+INTER_STRUCTURE)
  294.           offset++;
  295.       }
  296.       break;
  297.       }
  298.     }
  299.     switch(car)
  300.     {
  301.       case '-':
  302.       case KEY_LEFT:
  303.     return 1;
  304.     }
  305.   } while(quit==0);
  306.   return -1;
  307. }
  308.  
  309. void delete_list_file(t_file_data *file_list)
  310. {
  311.   t_file_data *current_file=file_list;
  312.   /* Libere la memoire */
  313.   while(current_file!=NULL)
  314.   {
  315.     t_file_data *next=current_file->next;
  316.     FREE(current_file);
  317.     current_file=next;
  318.   }
  319. }
  320.  
  321. int dir_partition(t_param_disk *disk_car, const t_diskext *partition, t_dir_data *dir_data, const unsigned long int inode)
  322. {
  323.   t_file_data *dir_list;
  324.   long int new_inode;
  325.   if(dir_data->debug!=0)
  326.     ecrit_rapport("\ndir_partition inode=%ld\n",inode);
  327.   dir_list=dir_data->get_dir(disk_car,partition,dir_data,inode);
  328.   dir_aff_log(disk_car, partition, dir_data, dir_list);
  329.   do
  330.   {
  331.     unsigned int current_directory_namelength=strlen(dir_data->current_directory);
  332.     new_inode=dir_aff(disk_car,partition,dir_data,dir_list,inode);
  333.     if(new_inode==0 || new_inode>1)
  334.     {
  335.       if(dir_partition(disk_car, partition, dir_data, (unsigned long int)new_inode)<0)
  336.       { /* quit */
  337.     delete_list_file(dir_list);
  338.     return -1;
  339.       }
  340.       /* back */
  341.       dir_data->current_directory[current_directory_namelength]='\0';
  342.     }
  343.   } while(new_inode==0 || new_inode>1);
  344.   delete_list_file(dir_list);
  345.   return new_inode;
  346. }
  347.  
  348.